home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / misc / conutils / CAP.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-07  |  6.2 KB  |  231 lines

  1. /*
  2.  * CAP - Console Access Protection
  3.  *
  4.  * This provides security from physical access to your conoles.
  5.  * When you run this program, it will clear the screen and prompt
  6.  * for a password. After so many failed attempts it will lock the
  7.  * tty and not allow them to try anymore. While this program is
  8.  * running, they can't abort this program, and they can not switch
  9.  * consoles either. The only only way around this is to reboot the
  10.  * computer, in which case it will be obvious that someone tried to
  11.  * access your server's consoles. This will log the date and time
  12.  * the person tried to get access into your console.
  13.  *
  14.  * To compile: [g]cc -o CAP CAP.c -ltermcap [-lcrypt]
  15.  * If you *not* have shadow passwords compile with -DNO_USE_SHADOW
  16.  * To compile in debug (or testing) mode, compile with -DDEBUG.
  17.  *
  18.  * Shok (Matt Conover), shok@dataforce.net
  19.  */
  20.  
  21. #include <pwd.h>
  22. #include <term.h>
  23. #include <stdio.h>
  24. #include <fcntl.h>
  25. #include <errno.h>
  26. #include <unistd.h>
  27. #include <stdlib.h>
  28. #include <signal.h>
  29. #include <syslog.h>
  30. #include <shadow.h>
  31. #include <linux/vt.h>
  32. #include <sys/stat.h>
  33. #include <sys/ioctl.h>
  34. #include <sys/types.h>
  35.  
  36. #define ERROR -1
  37. #define SAME   0
  38. #define LOCKOUT 3 /* How long in minutes to lock out of the console.     */
  39. #define MAXFAIL 3 /* Number of times they can enter an invalid password. */
  40.                   /* before being locked out for LOCKOUT minutes.        */
  41.  
  42. /* Used to disable switching consoles. */
  43. #define LOCKVT(x)     if ((ioctl(fd, VT_LOCKSWITCH, 1)) == ERROR) {    \
  44.                          perror("locking console (/dev/tty/)");        \
  45.                          exit(ERROR);                                  \
  46.                       }
  47.  
  48. /* Used to reenable ability to switch consoles. */
  49. #define UNLOCKVT(x)   if ((ioctl(fd, VT_UNLOCKSWITCH, 1)) == ERROR) {  \
  50.                          perror("locking console (/dev/tty/)");        \
  51.                          exit(ERROR);                                  \
  52.                       }
  53.  
  54.  
  55. int fd; /* Console fd. */
  56.  
  57. char *strip(char *str); /* Used to strip newlines from ctime().          */
  58. #ifdef DEBUG
  59. void sighandler(int signum);
  60. #endif DEBUG
  61.  
  62. int main()
  63. {
  64.   int uid;
  65.   int failed    = 0; /* Number of failed attempts out of MAXFAIL.      */
  66.   int totfailed = 0; /* Number of total failed attempts (not reseted). */
  67.   
  68.   time_t tm;
  69.  
  70.   char curtime[64];
  71.  
  72.   /* Don't change passwd or realpasswd's length. This is the maximum */
  73.   /* password length allow from getpass(). Any smaller can overflow. */
  74.   char *pass, passwd[128], realpasswd[128]; 
  75.  
  76.   struct passwd *pwd;
  77. #ifndef NO_USE_SHADOW
  78.   struct spwd   *spwd;
  79. #endif
  80.  
  81.   if ((fd = open("/dev/tty", O_RDWR)) == ERROR) {
  82.     perror("opening console (/dev/tty)");
  83.     exit(ERROR);
  84.   }
  85.   
  86.   /* Disable signals (so attackers can't abort program). */
  87.  
  88. #ifndef DEBUG
  89.    signal(SIGHUP,  SIG_IGN);
  90.    signal(SIGINT,  SIG_IGN);
  91.    signal(SIGTERM, SIG_IGN);
  92.    signal(SIGQUIT, SIG_IGN);
  93.    signal(SIGTSTP, SIG_IGN);
  94. #else
  95.    signal(SIGINT, sighandler);
  96.    signal(SIGTERM, sighandler);
  97.    signal(SIGQUIT, sighandler);
  98.    signal(SIGTSTP, sighandler);
  99.    signal(SIGSEGV, sighandler);
  100. #endif
  101.  
  102.   LOCKVT(fd); /* Lock the VT. It can no longer switch. */
  103.  
  104.   uid = getuid();
  105.   pwd = getpwuid(uid);
  106. #ifndef NO_USE_SHADOW
  107.   if ((spwd = getspnam(pwd->pw_name)) == NULL) {
  108.      perror("getspnam");
  109.      exit(ERROR);
  110.   }
  111.  
  112.   strncpy(realpasswd, spwd->sp_pwdp, sizeof(realpasswd));  
  113. #else
  114.   strncpy(realpasswd, pwd->pw_passwd, sizeof(realpasswd)); 
  115. #endif  
  116.  
  117.   clr();
  118.   printf("w00w00!\n");
  119.   printf("Console is now locked.\n");
  120.   getchar();
  121.  
  122.   /* Used to log invalid password attempts. */
  123.   openlog("CAP/conprot", LOG_CONS, LOG_AUTHPRIV); 
  124.  
  125.   while (1) {
  126.      /* Get the password from the user. */
  127.  
  128.      /* For some reason I get warnings without the typecast (broken
  129.         prototype?). */
  130.      pass = getpass("Enter password: ");
  131.  
  132.      
  133.      /* Encrypt the password from getpass(). 
  134.      /* Note, we are using realpasswd for our salt. This is to allow a */
  135.      /* salt of any size. This also saving us the trouble of getting   */
  136.      /* the salt ourselves.                           */
  137.      strncpy(passwd, crypt(pass, realpasswd), sizeof(passwd));
  138.  
  139.      passwd[128] = '\0'; /* NULL terminate passwd just to be safe.     */
  140.  
  141. #ifdef DEBUG
  142.      printf("Encrypted password from user: %s\n", passwd);
  143.      printf("The real encrypted password: %s\n", realpasswd);
  144. #endif
  145.  
  146.      if ((strcmp(passwd, realpasswd)) == SAME) {
  147.         /* Unlock the console, to allow it to switch. */
  148.         UNLOCKVT(fd);
  149.  
  150.         closelog(); /* Close logging. */
  151.  
  152.     clr();
  153.  
  154.         printf("Everything is now restored.\n");
  155.  
  156.         if (totfailed == 0) printf("No one tried to access the console.\n");
  157.         else printf("Total number of failed attempts to unlock console: %d\n",
  158.                 totfailed);
  159.  
  160.         exit(0);
  161.      } else {
  162.     failed++, totfailed++; /* Increase number of failed attempts. */
  163.  
  164.         /* Log bad attempts to syslog. */
  165.         tm = time(NULL);
  166.  
  167.         snprintf(curtime, sizeof(curtime), (char *)ctime(&tm));
  168.         strip(curtime); /* Strip new lines out of the time. */
  169.         syslog(LOG_WARNING, "Failed access attempt on: %s", curtime);
  170.  
  171.         printf("Invalid password.\n");
  172.  
  173.     if (failed >= MAXFAIL) {
  174.        printf("Maximum number of failed attempts.\n"
  175.                   "Now locking for %d minutes.\n", LOCKOUT);
  176.  
  177.        sleep(LOCKOUT * 60); /* Convert the minutes to seconds. */
  178.        failed = 0; /* Reset the number of failed attempts.     */
  179.         }
  180.      }
  181.   }
  182.  
  183.   return 0;
  184. }
  185.  
  186. char *strip(char *str)
  187. {
  188.   register int i;
  189.  
  190.   for (i = 0; str[i]; i++) 
  191.       /* Strip newline out of string. */
  192.       /* We do this because syslog appends the newline itself. */
  193.       if (str[i] == '\n') str[i] = '\0'; 
  194.  
  195.   return str;
  196. }
  197.  
  198. #ifdef DEBUG
  199. void sighandler(int signum)
  200. {
  201.   if (signum == 11) printf("Received SIGSEGV.\n");
  202.   printf("\nAborting and unlocking console.\n");
  203.  
  204.   UNLOCKVT(fd);
  205.  
  206.   if (signum == 11) kill(getpid(), 11);
  207.   exit(0);
  208. }
  209. #endif
  210.  
  211. clr()
  212. {
  213.   char *clear;
  214.   char clbuf[1024], *clbp = clbuf;
  215.  
  216.   if (tgetent(clbuf, getenv("TERM")) == ERROR) {
  217.      perror("tgetent");
  218.      system("clear");
  219.      return;
  220.   }
  221.  
  222.   if ((clear = tgetstr("cl", &clbp)) == NULL) {
  223.      perror("tgetent");
  224.      system("clear");
  225.      return;
  226.   }
  227.  
  228.   if (clear)
  229.      tputs(clear, tgetnum("li"), putchar);
  230. }
  231.